package com.v1.video.widgets;

import java.util.Locale;

import com.v1.video.R;
import com.v1.video.interfaces.OnControllerCallBackListener;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.MediaController.MediaPlayerControl;
import android.widget.PopupWindow;

public abstract class MediaPlayerUIController extends FrameLayout {
	protected OnControllerCallBackListener onControllerListener;
	protected MediaPlayerControl mediaPlayer;
	protected PopupWindow mPopupWindow;
	protected Context mContext;
	protected View rootView;
	private boolean isShowing = false;
	private boolean mIsDragging = false;

	protected final int PROGRESS_MAX = 1000;
	private static final int sDefaultTimeout = 3000;

	protected int mWindowWidth, mWindowHeight;

	private static final int FADE_OUT = 1;
	private static final int SHOW_PROGRESS = 2;
	
	public static final int SEEKBAR_ON_START = 0;
	public static final int SEEKBAR_ON_PROGRESSING = 1;
	public static final int SEEKBAR_ON_END = 2;

	protected SeekBar seekbar;
	protected TextView timeTv;
	protected TextView lengthTv;
	protected View switchLandPortrait;
	protected ImageView clickBack;
	protected ImageView playVideo;

	private long mDuration;

	public MediaPlayerUIController(Context context) {
		super(context);
		mContext = context;
		mPopupWindow = new PopupWindow(mContext);
		mPopupWindow.setFocusable(false);
		mPopupWindow.setBackgroundDrawable(null);
		mPopupWindow.setOutsideTouchable(true);
		mPopupWindow.setAnimationStyle(android.R.style.Animation);
	}

	public void setOnControllerListener(OnControllerCallBackListener listener) {
		this.onControllerListener = listener;
	}

	protected abstract View makeControllerLayout();

	protected abstract void initControllerView(View contrllerLayout);

	protected abstract void setWindow();

	public void setMediaPlayer(MediaPlayerControl mediaPlayer) {
		this.mediaPlayer = mediaPlayer;
	}

	public void setAnchorView(View rootView) {
		this.rootView = rootView;
		View view = makeControllerLayout();
		mPopupWindow.setContentView(view);
		initControllerView(view);
	}

	public void show() {
		if(onControllerListener != null){
			onControllerListener.show();
		}
		show(sDefaultTimeout);
	}

	public void show(int timeout) {
		mHandler.removeMessages(FADE_OUT);
		if (timeout != 0) {
			mHandler.sendMessageDelayed(mHandler.obtainMessage(FADE_OUT), timeout);
		} else {
			mHandler.sendMessageDelayed(mHandler.obtainMessage(FADE_OUT), sDefaultTimeout);
		}
		if (!isShowing) {
			setWindow();
			isShowing = true;
			mHandler.sendEmptyMessage(SHOW_PROGRESS);
		}
	}

	public void hide() {
		if (isShowing) {
			mPopupWindow.dismiss();
			isShowing = false;
			
			if(onControllerListener != null){
				onControllerListener.hide();
			}
		}
	}

	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			long pos;
			switch (msg.what) {
			case FADE_OUT:
				hide();
				break;
			case SHOW_PROGRESS:
				pos = setProgress();
				if (!mIsDragging && isShowing) {
					msg = obtainMessage(SHOW_PROGRESS);
					sendMessageDelayed(msg, 1000 - (pos % 1000));
				}
				break;
			}
		}
	};

	private long setProgress() {
		if (mediaPlayer == null || mIsDragging) {
			return 0;
		}

		int position = mediaPlayer.getCurrentPosition();
		int duration = mediaPlayer.getDuration();
		if (seekbar != null) {
			if (duration > 0 && position > 0) {
				long pos = 1000L * position / duration;
				seekbar.setProgress((int) pos);
			}
			int percent = mediaPlayer.getBufferPercentage();
			seekbar.setSecondaryProgress(percent * 10);
		}

		mDuration = duration;

		if (lengthTv != null && mDuration >= 0) {
			lengthTv.setText(generateTime(mDuration));
		}
		if (timeTv != null && position > 0) {
			timeTv.setText(generateTime(position));
		}
		return position;
	}

	private static String generateTime(long position) {
		int totalSeconds = (int) (position / 1000);

		int seconds = totalSeconds % 60;
		int minutes = (totalSeconds / 60) % 60;
		int hours = totalSeconds / 3600;

		if (hours > 0) {
			return String.format(Locale.US, "%02d:%02d:%02d", hours, minutes,
					seconds).toString();
		} else {
			return String.format(Locale.US, "%02d:%02d", minutes, seconds)
					.toString();
		}
	}

	protected OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {

		public void onStartTrackingTouch(SeekBar bar) {
			mIsDragging = true;
			mHandler.removeMessages(FADE_OUT);
			mHandler.removeMessages(SHOW_PROGRESS);
			if(onControllerListener != null){
				onControllerListener.onSeekBarDragChange(SEEKBAR_ON_START);
			}
		}

		public void onProgressChanged(SeekBar bar, int progress,
				boolean isFromUser) {
			if (!isFromUser) {
				return;
			}
			long newPosition = (mDuration * progress) / 1000;
			String time = generateTime(newPosition);
			if (timeTv != null) {
				timeTv.setText(time);
			}
			
			if(onControllerListener != null){
				onControllerListener.onSeekBarDragChange(SEEKBAR_ON_PROGRESSING);
			}
		}

		public void onStopTrackingTouch(SeekBar bar) {
			mIsDragging = false;
			mediaPlayer.seekTo((int) ((mDuration * bar.getProgress()) / 1000));
			show(sDefaultTimeout);
			mHandler.removeMessages(SHOW_PROGRESS);
			mHandler.sendEmptyMessage(SHOW_PROGRESS);
			if(onControllerListener != null){
				onControllerListener.onSeekBarDragChange(SEEKBAR_ON_END);
			}
		}
	};

	public void updateVideoPalyerUI(boolean isPlay) {
		playVideo.setVisibility(View.VISIBLE);
		if (isPlay) {
			playVideo.setImageResource(R.drawable.btn_play_video_pause);
		} else {
			playVideo.setImageResource(R.drawable.btn_play_video);
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_UP:

			break;
		case MotionEvent.ACTION_DOWN: // 临时这样处理吧，这个被播放器拦截了，全屏和小平有冲突
			if (!isShowing) {
				show();
			} else {
				hide();
			}
			break;
		}
		return super.onTouchEvent(event);
	}

}
